package main

import "fmt"

// Beverage 是抽象类，定义饮料制作的模板方法
type Beverage interface {
	BoilWater()           // 烧水
	Brew()                // 冲泡
	PourInCup()           // 倒入杯子
	AddCondiments()       // 添加调料
	WantCondiments() bool // 是否添加调料（钩子方法）
}

// MakeBeverage 是模板方法
func MakeBeverage(b Beverage) {
	b.BoilWater()
	b.Brew()
	b.PourInCup()
	if b.WantCondiments() {
		b.AddCondiments()
	}
}

// Coffee 是具体类：咖啡
type Coffee struct{}

func (c *Coffee) BoilWater() {
	fmt.Println("Boiling water")
}

func (c *Coffee) Brew() {
	fmt.Println("Brewing coffee")
}

func (c *Coffee) PourInCup() {
	fmt.Println("Pouring coffee into cup")
}

func (c *Coffee) AddCondiments() {
	fmt.Println("Adding sugar and milk")
}

func (c *Coffee) WantCondiments() bool {
	return true
}

// Tea 是具体类：茶
type Tea struct{}

func (t *Tea) BoilWater() {
	fmt.Println("Boiling water")
}

func (t *Tea) Brew() {
	fmt.Println("Steeping tea")
}

func (t *Tea) PourInCup() {
	fmt.Println("Pouring tea into cup")
}

func (t *Tea) AddCondiments() {
	fmt.Println("Adding lemon")
}

func (t *Tea) WantCondiments() bool {
	return false
}

func main() {
	// 制作咖啡
	fmt.Println("Making coffee:")
	coffee := &Coffee{}
	MakeBeverage(coffee)

	// 制作茶
	fmt.Println("\nMaking tea:")
	tea := &Tea{}
	MakeBeverage(tea)
}
